using Aspose.Cells;
using EasingCore;
using FancyScrollView;
using GameProtocol;
using Google.Protobuf.WellKnownTypes;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Remoting.Contexts;
using TEngine;
using UnityEngine;
using UnityEngine.UIElements;

namespace GameLogic
{
    enum Alignment
    {
        Upper,
        Middle,
        Lower,
    }
    public class LoopScrollViewItemData
    {
        int m_ID;
        string m_Message;
        public int ID { get => m_ID; set => m_ID = value; }
        public string Message { get => m_Message; set => m_Message = value; }
        public LoopScrollViewItemData(int id, string message ="")
        { 
            m_ID = id;
            m_Message = message; 
        }
    }
    public class LoopScrollViewItemContext: FancyScrollRectContext
    {
        public int SelectedIndex = -1;
        public Action<int> OnCellClicked;
    }
    public class LoopScrollView : FancyScrollRect<LoopScrollViewItemData, LoopScrollViewItemContext>
    {
        [SerializeField]
        private float m_CellSize = 100;
        Func<string> itemPathHandle;
        Action<LoopScrollViewItemData, LoopScrollViewItemView> refreshHandle;
        Action<LoopScrollViewItemData, LoopScrollViewItemView> selectedHandle;
        FancyScrollView.Scroller scroller = default;

        public int SelectedIndex { get { return Context.SelectedIndex ; } }
        protected override GameObject CellPrefab { get {
                if (!m_CellPrefab)
                {
                    m_CellPrefab = GameModule.Resource.LoadAsset<GameObject>(itemPathHandle.Invoke());
                    m_CellPrefab.GetOrAddComponent<LoopScrollViewItemView>();
                }
                return m_CellPrefab;
            } }

        protected override float CellSize{get{return m_CellSize; } }

        GameObject m_CellPrefab;
        private void Awake()
        {
            scroller = gameObject.GetOrAddComponent<FancyScrollView.Scroller>();
        }

        // Start is called before the first frame update
        void Start()
        {
        
        }

        // Update is called once per frame
        void Update()
        {

        }
        protected override void Initialize()
        {
            base.Initialize();

            Context.OnCellClicked = SelectCell;

            //scroller.OnValueChanged(UpdatePosition);
            //scroller.OnSelectionChanged(UpdateSelection);
        }
        public void UpdateData(IList<LoopScrollViewItemData> items)
        {
            UpdateContents(items);
            //scroller.SetTotalCount(items.Count);
        }
        public void SelectCell(int index)
        {
            if (index < 0 || index >= ItemsSource.Count || index == Context.SelectedIndex)
            {
                Context.SelectedIndex = index;
                Refresh();
                return;
            }

            UpdateSelection(index);
            ScrollTo(index, 0.3f, Ease.InOutQuint, GetAlignment(Alignment.Middle));
            //JumpTo(index, GetAlignment(Alignment.Middle));
        }
        protected override void OnCellUpdateContent(FancyCell<LoopScrollViewItemData, LoopScrollViewItemContext> cell, LoopScrollViewItemData data)
        {
            refreshHandle(data, cell as LoopScrollViewItemView);
            if(Context.SelectedIndex == cell.Index)
            {
                selectedHandle.Invoke(data, cell as LoopScrollViewItemView);
            }
        }
        void UpdateSelection(int index)
        {
            if (Context.SelectedIndex == index)
            {
                return;
            }
             
            Context.SelectedIndex = index;
            Refresh();
        }
        float GetAlignment(Alignment alignment)
        {
            switch (alignment)
            {
                case Alignment.Upper: return 0.0f;
                case Alignment.Middle: return 0.5f;
                case Alignment.Lower: return 1.0f;
                default: return GetAlignment(Alignment.Middle);
            }
        }
        public void SetItemSelectedFunc(Action<LoopScrollViewItemData, LoopScrollViewItemView> func)
        {
            selectedHandle = func;
        }
        // 指定生成的prefab路径，每个item刷新时调用 | Specify the generated prefab path, which is called when each item is refreshed
        public void SetSpawnPrefabPath(Func<string> func)
        {
            itemPathHandle = func;
        }

        // 指定刷新方法的回调，每个item刷新时调用 | Specifies the callback of the refresh method, which is called when each item is refreshed
        public void SetRefreshFunc(Action<LoopScrollViewItemData, LoopScrollViewItemView> func)
        {
            refreshHandle = func;
        }
    }
}
